/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
namespace System.Qizx.Util.IO
{
	
	/// <summary>    Reads bytes from a list of data blocks.
	/// Blocks are first added, then reading can begin. Blocks can be
	/// of variable size, but only the last one may be incompletely filled.
	/// </summary>
	[Serializable]
	public class CoreByteInput:ByteInputBase
	{
		internal sbyte[][] blocks;
		internal int[] blockSizes;
		internal int blockCount;
		internal int blockPtr;
		
		public CoreByteInput():base(8192)
		{
			blocks = new sbyte[4][];
			blockSizes = new int[blocks.Length];
		}
		
		public CoreByteInput(CoreByteOutput source):base(source.bufferSize)
		{
			blocks = source.blocks;
			blockSizes = source.blockSizes;
			blockCount = source.blockCount;
		}
		
		public CoreByteInput(sbyte[] data, int size):base(data, size)
		{
		}
		
		public virtual void  restartOn(sbyte[] buffer, int size)
		{
			this.data = buffer;
			this.bufSize = size;
			this.ptr = 0;
		}
		
		protected internal override int readBuffer()
		{
			
			if (blockPtr >= blockCount)
				return - 1;
			int bkSize = (blockSizes == null)?blocks[blockPtr].Length:blockSizes[blockPtr];
			Array.Copy(blocks[blockPtr], 0, data, 0, bkSize);
			++blockPtr;
			return bkSize;
		}
		
		public virtual void  store(sbyte[] data, int size)
		{
			if (blockCount >= blocks.Length)
			{
				sbyte[][] old = blocks;
				blocks = new sbyte[old.Length * 2][];
				Array.Copy(old, 0, blocks, 0, old.Length);
				int[] olds = blockSizes;
				blockSizes = new int[old.Length * 2];
				Array.Copy(olds, 0, blockSizes, 0, old.Length);
			}
			blocks[blockCount] = data;
			blockSizes[blockCount++] = size;
		}
	}
}